﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Text;

namespace Comteck.Dto.Common {
  [AttributeUsage(AttributeTargets.Property)]
  public class MaxValueAttribute : ValidationAttribute {
    public double MaxValue { get; }

    public MaxValueAttribute(double maxValue) {
      this.MaxValue = maxValue;
    }
  }

  public static class MaxValueExtension {
    public static bool LessThan<T>(this T t, string propertyName, out decimal maxValue) where T : new() {
      maxValue = decimal.Zero;
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MaxValueAttribute))) {
        MaxValueAttribute attribute = (MaxValueAttribute) pi.GetCustomAttribute(typeof(MaxValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          maxValue = attribute.MaxValue.To<decimal>();

          return value < maxValue;
        }
      }

      return true;
    }

    public static bool LessEqualThan<T>(this T t, string propertyName, out decimal maxValue) where T : new() {
      maxValue = decimal.Zero;
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MaxValueAttribute))) {
        MaxValueAttribute attribute = (MaxValueAttribute) pi.GetCustomAttribute(typeof(MaxValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          maxValue = attribute.MaxValue.To<decimal>();

          return value <= maxValue;
        }
      }

      return true;
    }

    public static void LessThanValidate<T>(this T t, string propertyName) where T : new() {
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MaxValueAttribute))) {
        MaxValueAttribute attribute = (MaxValueAttribute) pi.GetCustomAttribute(typeof(MaxValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          if (value >= attribute.MaxValue.To<decimal>()) {
            throw new ComteckException(string.Format(attribute.ErrorMessage, propertyName, attribute.MaxValue));
          }
        }
      }
    }

    public static void LessEqualThanValidate<T>(this T t, string propertyName) where T : new() {
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MaxValueAttribute))) {
        MaxValueAttribute attribute = (MaxValueAttribute) pi.GetCustomAttribute(typeof(MaxValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          if (value > attribute.MaxValue.To<decimal>()) {
            throw new ComteckException(string.Format(attribute.ErrorMessage, propertyName, attribute.MaxValue));
          }
        }
      }
    }
  }
}
